home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 December / CHIPNET Aralık 1997.iso / linux / redhat / misc / src / install / run.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-11  |  3.7 KB  |  190 lines

  1. #include <alloca.h>
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/wait.h>
  8. #include <unistd.h>
  9.  
  10. #include "newt.h"
  11. #include "log.h"
  12. #include "run.h"
  13. #include "windows.h"
  14.  
  15. int runProgramRoot(enum runType runType, char * root, char * name, 
  16.            char ** args) {
  17.     return runProgramIORoot(runType, root, name, args, NULL, NULL);
  18. }
  19.  
  20. int runProgramIO(enum runType runType, char * name, char ** args, char * in,
  21.          char ** out) {
  22.     return runProgramIORoot(runType, NULL, name, args, in, out);
  23. }
  24.  
  25. int runProgramIORoot(enum runType runType, char * root, char * name, 
  26.         char ** args, char * in, char ** out) {
  27.  
  28.     char * buf;
  29.     int infd, outfd, errfd, status, i;
  30.     int resultfd = 0;
  31.     pid_t pid;
  32.     char ** currarg;
  33.     int inputPipe[2], outputPipe[2];
  34.     char resultbuf[200];
  35.     char * result;
  36.     int resultSize;
  37.     char fullname[200];
  38.  
  39.     /* if "in" is set, it better be short. We assume one write() call is
  40.        enough */
  41.  
  42.     if (root) {
  43.     sprintf(fullname, "%s/%s", root, name);
  44.     } else 
  45.     strcpy(fullname, name);
  46.  
  47.     i = 0;
  48.     i = strlen(name) + 50;
  49.     
  50.     currarg = args;
  51.     while (*currarg) {
  52.     i += strlen(*currarg) + 1;
  53.     currarg++;
  54.     }
  55.  
  56.     buf = alloca(i);
  57.  
  58.     if (testing) 
  59.     strcpy(buf, "if I weren't testing I would run:\n\n");
  60.     else
  61.     strcpy(buf, "running: ");
  62.  
  63.     strcat(buf, name);
  64.     strcat(buf, " ");
  65.     
  66.     currarg = args;
  67.     while (*currarg) {
  68.     strcat(buf, *currarg);
  69.     strcat(buf, " ");
  70.     currarg++;
  71.     }
  72.  
  73.     if (testing) {
  74.     newtComponent t, f, succeed, fail;
  75.  
  76.     newtOpenWindow(17, 4, 45, 15, "Running");
  77.  
  78.     succeed = newtButton(8, 10, "Succeed");
  79.     fail = newtButton(28, 10, "Fail");
  80.     t = newtTextbox(2, 1, 40, 13, NEWT_TEXTBOX_WRAP | NEWT_TEXTBOX_SCROLL);
  81.     newtTextboxSetText(t, buf);
  82.     f = newtForm(NULL, NULL, 0);
  83.  
  84.     newtFormAddComponents(f, t, succeed, fail, NULL);
  85.  
  86.     t = newtRunForm(f);
  87.      
  88.     newtFormDestroy(f);
  89.     newtPopWindow();
  90.  
  91.     return t == fail;
  92.     } 
  93.  
  94.     if (access(fullname,  X_OK))  {
  95.     logMessage("cannot run %s: %s", fullname, strerror(errno));
  96.     messageWindow("Error", "I cannot run %s: %s", fullname, 
  97.                 strerror(errno));
  98.     return -1;
  99.     }
  100.     
  101.  
  102.     logMessage(buf);
  103.  
  104.     if (root)
  105.     logMessage("    root is %s", root);
  106.  
  107.     if (in) {
  108.     pipe(inputPipe);
  109.     write(inputPipe[1], in, strlen(in));
  110.     close(inputPipe[1]);
  111.     infd = inputPipe[0];
  112.     } else {
  113.     infd = open("/dev/null", O_RDONLY);
  114.     }
  115.  
  116.     errfd = open("/dev/tty5", O_APPEND | O_CREAT);
  117.     if (errfd < 0)
  118.     errfd = open("/tmp/exec.log", O_APPEND | O_CREAT);
  119.  
  120.     if (out) {
  121.     pipe(outputPipe);
  122.     outfd = outputPipe[1];
  123.     resultfd = outputPipe[0];
  124.     } else if (runType & RUN_LOG) {
  125.     outfd = open("/dev/tty5", O_RDWR);
  126.     if (outfd < 0)
  127.         outfd = open("/tmp/exec.log", O_APPEND | O_CREAT);
  128.     } else
  129.     outfd = open("/dev/null", O_RDWR);
  130.  
  131.     if (!(pid = fork())) {
  132.     close(0);
  133.     close(1);
  134.     close(2);
  135.     
  136.     if (root) {
  137.         chroot(root);
  138.         chdir("/");
  139.     }
  140.  
  141.     dup2(infd, 0);
  142.     dup2(outfd, 1);
  143.     dup2(errfd, 2);
  144.  
  145.     close(infd);
  146.     close(outfd);
  147.     close(errfd);
  148.     if (out) close(resultfd);
  149.  
  150.     execv(name, args);
  151.     logMessage("exec of %s failed: %s", name, strerror(errno));
  152.     exit(-1);
  153.     }
  154.  
  155.     close(infd);
  156.     close(outfd);
  157.     close(errfd);
  158.  
  159.     if (out) {
  160.     resultSize = 0;
  161.     result = NULL;
  162.  
  163.     do { 
  164.         i = read(resultfd, resultbuf, sizeof(resultbuf));
  165.  
  166.         if (!result) {
  167.         result = malloc(i + 1);
  168.         } else 
  169.         result = realloc(result, resultSize + i + 1);
  170.         memcpy(result + resultSize, resultbuf, i);
  171.         resultSize += i;
  172.         result[resultSize] = '\0';
  173.     } while (i > 0);
  174.  
  175.         close(resultfd);
  176.     *out = result;
  177.     }
  178.  
  179.     waitpid(pid, &status, 0);
  180.  
  181.     if (WIFEXITED(status))
  182.     return WEXITSTATUS(status);
  183.  
  184.     return -1;
  185. }
  186.  
  187. int runProgram(enum runType runType, char * name, char ** args) {
  188.     return runProgramIO(runType, name, args, NULL, NULL);
  189. }
  190.